export interface Hook {
    before?: Function;
    after?: Function;
}
class HookInstance {
    constructor() {}
    _before: Function[] = [];
    _after: Function[] = [];
}
const symbol = Symbol("hook private");

/* 用于在一个函数前或者后进行特定函数事件的执行 */
export function hook<T>(obj: T, key: string, { before, after }: Hook) {
    const old = obj[key];
    if (typeof old !== "function") return false;
    if (!old._hooked) {
        obj[key] = function (...args: any[]) {
            const instance = obj[key][symbol] as HookInstance;
            instance._before.forEach((i) => i.apply(this, args));
            const result = old.apply(this, args);
            instance._after.forEach((i) => i.apply(this, args));
            return result;
        };
        const instance = new HookInstance();
        obj[key][symbol] = instance;
        obj[key]._hooked = true;
        if (after) instance._after = [after];
        if (before) instance._before = [before];
    } else {
        const instance = obj[key][symbol];
        if (after) instance._after.push(after);
        if (before) instance._before.push(before);
    }
    return true;
}
